#ifndef RANDOM_HPP
#define RANDOM_HPP

#include <cstddef>
#include <cmath>

template <typename Type>
class random_generator{
public:
    virtual ~random_generator(){}
    virtual Type next()=0;
    Type operator()(){
        return next();
    }
    Type operator()(Type range){
        return next()%range;
    }
};

class SystemRandom:public random_generator<unsigned int>{
public:
    SystemRandom();
    ~SystemRandom();
    unsigned int next();
private:
    void *device;
};

class ClibRandom:public random_generator<unsigned int>{
public:
    ClibRandom(unsigned int seed);
    ~ClibRandom();
    unsigned int next();
};

class Mt19937Random:public random_generator<unsigned int>{
public:
    Mt19937Random(unsigned int seed);
    ~Mt19937Random();
    unsigned int next();
private:
    void *device;
};

#endif // RANDOM_HPP

